package org.wisdom.ab.apis.controller;

import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.EmptyResultDataAccessException;
import org.wisdom.ab.apis.DepartmentController;
import org.wisdom.ab.apis.assembler.DepartmentAssembler;
import org.wisdom.ab.domain.department.entity.AbDepartment;
import org.wisdom.ab.domain.department.repository.DepartmentRepository;
import org.wisdom.ab.domain.staff.repository.StaffRepository;
import org.wisdom.ab.dto.DepartmentDto;
import org.wisdom.annotation.WisdomController;
import org.wisdom.exception.BusinessException;
import org.wisdom.vo.ResponseResult;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;

/**
 * 部门管理API
 *
 * @author 张智研
 * @date 2022/05/16 08:08
 **/
@RequiredArgsConstructor
@WisdomController
public class DepartmentControllerImpl implements DepartmentController {

    private final DepartmentRepository departmentRepository;
    private final DepartmentAssembler departmentAssembler;
    private final StaffRepository staffRepository;

    @Override
    public ResponseResult<String> save(DepartmentDto departmentDto) {
        AbDepartment department = this.departmentAssembler.departmentDtoToEntity(departmentDto);
        department = this.departmentRepository.save(department);
        return ResponseResult.ok(department.getId());
    }

    @Override
    public ResponseResult<DepartmentDto> get(String departmentId) {
        Optional<AbDepartment> departmentOptional = this.departmentRepository.findById(departmentId);
        if (departmentOptional.isPresent()) {
            DepartmentDto departmentDto = this.departmentAssembler.departmentEntityToDto(departmentOptional.get());
            return ResponseResult.ok(departmentDto);
        } else {
            throw new BusinessException("部门{" + departmentId + "}不存在！");
        }

    }

    @Override
    public ResponseResult<String> delete(String departmentId) {
        List<AbDepartment> departmentList = this.departmentRepository.findByParentId(departmentId);
        if (!departmentList.isEmpty()) {
            throw new BusinessException("该部门下存在子部门，不允许删除！");
        }
        long n = this.staffRepository.countByDeptId(departmentId);
        if (n > 0) {
            throw new BusinessException("该部门下存在员工，不允许删除！");
        }
        try {
            this.departmentRepository.deleteById(departmentId);
        }catch (EmptyResultDataAccessException e) {
            throw new BusinessException("部门{" + departmentId + "}不存在，删除失败！");
        }
        return ResponseResult.ok();
    }

    @Override
    public ResponseResult<List<DepartmentDto>> list(String companyId, String departmentId) {
        List<DepartmentDto> departmentDtoList;
        List<AbDepartment> departmentList;
        if(ObjectUtil.isEmpty(departmentId)) {
            // 如果部门为空，则查询公司下所有部门
            departmentList = this.departmentRepository.findAllByCompanyId(companyId);
            departmentDtoList = this.departmentAssembler.departmentEntityToDto(departmentList);
        }else {
            Optional<AbDepartment> departmentOptional =
                    this.departmentRepository.findByCompanyIdAndId(companyId, departmentId);
            if (departmentOptional.isPresent()) {
                DepartmentDto departmentDto = this.departmentAssembler.departmentEntityToDto(departmentOptional.get());
                departmentList = this.departmentRepository
                        .findAllByCompanyIdAndDeptIdPathLike(companyId,departmentDto.getDeptIdPath().concat(departmentDto.getId()).concat("/") + "%");
                departmentDtoList = this.departmentAssembler.departmentEntityToDto(departmentList);
                departmentDtoList.add(departmentDto);
            } else {
                throw new BusinessException("部门{" + departmentId + "}不存在！");
            }
        }
        departmentDtoList.sort(Comparator.comparing(DepartmentDto::getOrder));
        return ResponseResult.ok(departmentDtoList);
    }

    @Override
    public ResponseResult<List<DepartmentDto>> listAll() {
        List<AbDepartment> departmentList = this.departmentRepository.findAll();
        List<DepartmentDto> departmentDtoList = this.departmentAssembler.departmentEntityToDto(departmentList);
        return ResponseResult.ok(departmentDtoList);
    }
}
